package model

import (
	"time"

	"bmember/pkg/util"
)

const (
	AccountOK         int8 = 1
	AccountAbandoned  int8 = 2
	AccountUnactivate int8 = 3
	AccountBlocked    int8 = 4

	AccountOKStr         = "ok"
	AccountAbandonedStr  = "abandoned"
	AccountUnactivateStr = "unactivate"
	AccountBlockedStr    = "blocked"
)

// MemberAccount 会员资产账户
type MemberAccount struct {
	Id         int64     `json:"id" sql:"id"`
	BrandId    int64     `json:"brand_id" sql:"brand_id"`       // 品牌id
	GroupId    int64     `json:"group_id" sql:"group_id"`       // 体系id
	CardId     int64     `json:"card_id" sql:"card_id"`         // 卡id
	MemberId   int64     `json:"member_id" sql:"member_id"`     // 会员id
	CardNumber string    `json:"card_number" sql:"card_number"` // 卡号
	Balance    uint64    `json:"balance" sql:"balance"`         // 余额
	Integral   uint64    `json:"integral" sql:"integral"`       // 积分余额
	Deposit    uint64    `json:"deposit" sql:"deposit"`         // 押金
	Status     int8      `json:"status" sql:"status"`           // 资产状态：1~正常，2~废弃，3~未激活 4~冻结
	CreatedAt  time.Time `json:"created_at" sql:"created_at"`
	UpdatedAt  time.Time `json:"updated_at" sql:"updated_at"`
	DeletedAt  int64     `json:"deleted_at" sql:"deleted_at"`
}

// NewMemberAccount 新建会员账户
func NewMemberAccount(brandId, groupId, cardId, memberId int64, cardNumber string) *MemberAccount {
	now := util.GetNow()
	return &MemberAccount{
		BrandId:    brandId,
		GroupId:    groupId,
		CardId:     cardId,
		MemberId:   memberId,
		CardNumber: cardNumber,
		Status:     AccountOK,
		CreatedAt:  now,
		UpdatedAt:  now,
	}
}

// IsValid 是否有效
func (a *MemberAccount) IsValid() bool {
	return a.Status == AccountOK && a.DeletedAt == 0
}

// UpdateCard 更新卡
func (a *MemberAccount) UpdateCard(cardId int64) {
	if a.CardId != cardId {
		a.CardId = cardId
		a.UpdatedAt = util.GetNow()
	}
}

// SetStatus 设置状态
func (a *MemberAccount) SetStatus(st int8) error {
	status := []int8{AccountOK, AccountAbandoned, AccountUnactivate, AccountBlocked}
	if !util.ContainInt8(status, st) {
		return InvalidEnum
	}
	a.Status = st
	a.UpdatedAt = util.GetNow()
	return nil
}

// UpdateBalance 更新金额
func (a *MemberAccount) UpdateBalance(op int8, amount uint64) error {
	switch op {
	case BalanceConsum, BalanceRechargeRefund, BalanceGiftRefund:
		a.Balance -= amount
	case BalanceConsumRefund, BalanceRecharge, BalanceGift, BalanceShiftIn:
		a.Balance += amount
	default:
		return InvalidEnum
	}
	a.UpdatedAt = util.GetNow()
	return nil
}

// UpdateIntegral 设置积分数
func (a *MemberAccount) UpdateIntegral(op int8, num uint64) error {
	switch op {
	case IntegralConsumRefund, IntegralExchange, IntegralAwardCancel, IntegralCleanUp:
		a.Integral -= num
	case IntegralConsum, IntegralExchangeRefund, IntegralAward, IntegralSignIn:
		a.Integral += num
	default:
		return InvalidEnum
	}
	a.UpdatedAt = util.GetNow()
	return nil
}

// AwardIntegral 赠送积分
func (a *MemberAccount) AwardIntegral(num uint64) {
	_ = a.UpdateIntegral(IntegralAward, num)
}

// ReturnAwardedIntegral 退赠送积分
func (a *MemberAccount) ReturnAwardedIntegral(num uint64) {
	_ = a.UpdateIntegral(IntegralAwardCancel, num)
}

// ConsumptionIntegral 消费积分
func (a *MemberAccount) ConsumptionIntegral(num uint64) {
	_ = a.UpdateIntegral(IntegralConsum, num)
}

// RefundConsumptionIntegral 消费退款
func (a *MemberAccount) RefundConsumptionIntegral(num uint64) {
	_ = a.UpdateIntegral(IntegralConsumRefund, num)
}

// ExchangeIntegral 积分兑换
func (a *MemberAccount) ExchangeIntegral(num uint64) {
	_ = a.UpdateIntegral(IntegralExchange, num)
}

// RefundExchangeIntegral 兑换退
func (a *MemberAccount) RefundExchangeIntegral(num uint64) {
	_ = a.UpdateIntegral(IntegralExchangeRefund, num)
}

// BalanceRecharge 余额充值
func (a *MemberAccount) BalanceRecharge(amount uint64) {
	_ = a.UpdateBalance(BalanceRecharge, amount)
}

// RechargeRefund 充值退
func (a *MemberAccount) RechargeRefund(amount uint64) {
	_ = a.UpdateBalance(BalanceRechargeRefund, amount)
}

// BalanceCashGift 现金赠送
func (a *MemberAccount) BalanceCashGift(amount uint64) {
	_ = a.UpdateBalance(BalanceGift, amount)
}

// CashGiftRefund 退款现金赠送
func (a *MemberAccount) CashGiftRefund(amount uint64) {
	_ = a.UpdateBalance(BalanceGiftRefund, amount)
}

// Consumption 余额消费
func (a *MemberAccount) Consumption(amount uint64) {
	_ = a.UpdateBalance(BalanceConsum, amount)
}

// ConsumptionRefund 消费退款
func (a *MemberAccount) ConsumptionRefund(amount uint64) {
	_ = a.UpdateBalance(BalanceConsumRefund, amount)
}
